use std::fmt::{Debug, Display, Formatter};
use std::ops::{Deref, DerefMut};
use std::pin::Pin;
use std::ptr::NonNull;
use std::slice::from_raw_parts;
use std::time::Duration;

use lazy_static::lazy_static;

// use crate::thread_safe_slice;

/// 提供一个线程安全的指针处理操作，需要自己保证在线程中是绝对安全的, 同时也要满足NonNullptr的全部特性
/// 1. 此类只提供简易访问被捕获变量的权限，不建议在多线程条件下作修改操作
/// 2. 此类并没有管理被捕获变量所有权，要注意被捕获变量的生命周期
pub struct ThreadSafePtr<T: ?Sized>(NonNull<T>, Option<usize>);

lazy_static! {
    /// 初始化全局锁，赋予sync,send能力
    static ref GLOBAL_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
    static ref THREAD_SAFE_LOCK: ThreadSafePtr<std::sync::Mutex<()>> =
        ThreadSafePtr::capture(&GLOBAL_LOCK);
}

impl<T: Display> Display for ThreadSafePtr<T> {
    /// 提供对ThreadSafePtr打印功能
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self.1.as_ref() {
            None => unsafe { write!(f, "{}", self.0.as_ref()) },
            Some(&len) => unsafe {
                let mut tmp = String::new();
                tmp.reserve(len);
                for i in 0..len {
                    tmp.push_str(format!("{}", self.0.as_ptr().add(i).as_ref().unwrap()).as_str());
                    tmp.push(',');
                }
                write!(f, "{}", tmp)
            },
        }
    }
}

impl<T: Debug> Debug for ThreadSafePtr<T> {
    /// 提供对ThreadSafePtr调试输出功能
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self.1.as_ref() {
            None => unsafe { write!(f, "{:?}", self.0.as_ref()) },
            Some(&len) => {
                write!(f, "{:?}", self.to_slice())
            }
        }
    }
}

impl<T: Sized> ThreadSafePtr<T> {
    /// 提供捕获数组功能，提供sync,send能力
    #[inline]
    pub fn capture_slice(val: &[T]) -> Self {
        Self(NonNull::from(unsafe { &*val.as_ptr() }), Some(val.len()))
    }

    /// 提供解包转数组功能
    #[inline]
    pub fn to_slice(&self) -> &[T] {
        unsafe {
            match self.1.as_ref() {
                None => {
                    panic!("slice requires len value")
                }
                Some(len) => std::slice::from_raw_parts(self.0.as_ptr(), *len),
            }
        }
    }

    /// 提供解包转数组功能mut
    #[inline]
    pub fn to_slice_mut(&mut self) -> &mut [T] {
        unsafe {
            match self.1.as_ref() {
                None => {
                    panic!("slice requires len value")
                }
                Some(len) => std::slice::from_raw_parts_mut(self.0.as_ptr(), *len),
            }
        }
    }
}

impl<T: ?Sized> ThreadSafePtr<T> {
    /// 提供捕获普通变量功能
    #[inline]
    pub fn capture(val: &T) -> Self {
        Self(NonNull::from(val), None)
    }
    pub fn is_slice(&self) -> bool {
        self.1.is_some()
    }

    /// 对捕获的变量直接赋值（unsafe操作，原变量内容直接被drop掉）
    pub unsafe fn unsafe_assign(&self, val: &T)
    where
        T: Clone,
    {
        *self.0.as_ptr() = val.clone();
    }

    /// 对捕获的变量直接赋值（同步的unsafe操作，原变量内容直接被drop掉）
    pub unsafe fn unsafe_assign_sync(&self, val: &T)
    where
        T: Clone,
    {
        let _unused = THREAD_SAFE_LOCK.lock().expect("acquired lock failed!!!");
        *self.0.as_ptr() = val.clone();
    }

    /// 解包获取指针
    pub fn get_ptr(&self) -> *mut T {
        self.0.as_ptr()
    }
}

impl<T: OptionTrait + ?Sized> ThreadSafePtr<T> {
    //提供精简的read_write操作
    pub fn read_write_ops(
        &mut self,
        func: impl Fn(<T as OptionTrait>::Target) -> Option<<T as OptionTrait>::Target>,
    ) {
        unsafe {
            // let mut0 = self.0.as_mut();
            self.0
                .as_mut()
                .replace(func(self.0.as_mut().take().unwrap()).unwrap());
        }
    }
}

impl<T: ?Sized> AsRef<T> for ThreadSafePtr<T> {
    fn as_ref(&self) -> &T {
        unsafe { self.0.as_ref() }
    }
}

impl<T: ?Sized> AsMut<T> for ThreadSafePtr<T> {
    fn as_mut(&mut self) -> &mut T {
        unsafe { self.0.as_mut() }
    }
}

impl<T: ?Sized> Deref for ThreadSafePtr<T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &Self::Target {
        unsafe { self.0.as_ref() }
    }
}

impl<T: ?Sized> DerefMut for ThreadSafePtr<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { self.0.as_mut() }
    }
}

impl<T: ?Sized> Clone for ThreadSafePtr<T> {
    fn clone(&self) -> Self {
        Self(self.0, self.1.clone())
    }
}

impl<T: ?Sized> Copy for ThreadSafePtr<T> {}

unsafe impl<T: ?Sized> Sync for ThreadSafePtr<T> {}

unsafe impl<T: ?Sized> Send for ThreadSafePtr<T> {}

pub trait OptionTrait {
    fn take(&mut self) -> Option<Self::Target>;
    fn replace(&mut self, t: Self::Target) -> Option<Self::Target>;
    type Target;
}

impl<T> OptionTrait for Option<T> {
    fn take(&mut self) -> Option<Self::Target> {
        self.take()
    }

    fn replace(&mut self, t: Self::Target) -> Option<Self::Target> {
        self.replace(t)
    }

    type Target = T;
}

#[test]
fn test_ptr1() {
    let ptr = "thread safe str".to_string();
    let mut ptr = ThreadSafePtr::capture(&ptr);

    let handle = std::thread::spawn(move || {
        std::thread::sleep(Duration::from_secs(2));
        println!("{}", ptr);
    });
    // 不会应为move失效
    *ptr.as_mut() = "ok".to_string();
    println!("{}", ptr);
    handle.join();
}

#[test]
fn test_ptr2() {
    let ptr = "thread safe str".to_string();
    let mut ptr = ThreadSafePtr::capture(&ptr);

    let handle = std::thread::spawn(move || {
        // 不会因为mut操作和move func操作冲突
        *ptr.as_mut() = "ok".to_string();
        println!("{}", ptr);
    });
    handle.join();

    println!("{}", ptr);
}
